package com.lz.gmall.order.listener;

import com.alibaba.fastjson.JSON;
import com.lz.gmall.order.service.OrderInfoService;
import com.lz.gmall.rabbit.constant.RabbitConstant;
import com.lz.gmall.rabbit.service.RabbitBizService;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;

import java.util.Map;


/**
 * @author 郭运龙
 */
@Component
public class OrderDelayListener {

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private RabbitBizService rabbitBizService;

    /**
     * 监听死信队列，如果有消息到达死信队列说明在规定时间未完成付款操作，进行关单
     * Message 对象表示从队列中接收到的消息
     * 消息标志（delivery tag）：用于标识消息在 RabbitMQ 服务器上的位置。
     * 每当一个消息被消费者接收后，其标志都会被更新。消费者可以使用标志来确认消息是否已经成功处理。
     *
     * msg相当于message.body()中的byte转换为string
     */
    @RabbitListener(queues = {RabbitConstant.DELAY_QUEUE_NAME})
    public void delayOrder(String msg, Message message,Channel channel){
        try {
            //获取到订单的参数
            Map<String,Object> map = JSON.parseObject(msg, Map.class);
            long orderId = Long.parseLong(map.get("orderId").toString());
            long userId = Long.parseLong(map.get("userId").toString());
            //进行关单操作
            orderInfoService.closeOrder(orderId,userId);
            //返回ack，拿到ack就会把死信队列中的消息删除掉
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
        } catch (Exception e) {
            try {
                //出现了异常，说明关单失败，返回nack,最后一个参数true表示失败继续重试，会一直重试（表示重新入队）
                //channel.basicNack(message.getMessageProperties().getDeliveryTag(),true,true);
                rabbitBizService.retryer(msg,message,channel,3L);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }

    }

}
